/**
 * 主应用程序入口
 * 集成所有模块，提供完整的PLC通信功能
 */
const config = require('./config/config');
const logger = require('./utils/logger');
const SiemensPLCAdapter = require('./adapters/siemens-plc-adapter');
const RockwellPLCAdapter = require('./adapters/rockwell-plc-adapter');
const DataCollector = require('./core/data-collector');
const DeviceController = require('./core/device-controller');

class PLCCommunicationApp {
  constructor() {
    this.adapters = new Map();
    this.dataCollector = new DataCollector({
      dataStoragePath: config.system.dataStoragePath
    });
    
    this.deviceController = new DeviceController({
      commandLogPath: `${config.system.dataStoragePath}/commands/`
    });
    
    // 注册事件处理
    this.setupEventHandlers();
  }

  /**
   * 设置事件处理器
   */
  setupEventHandlers() {
    // 数据采集事件
    this.dataCollector.on('data', (data) => {
      logger.debug(`收到数据: 设备=${data.deviceId}, 时间=${data.timestamp}`);
    });
    
    this.dataCollector.on('deviceError', (event) => {
      logger.error(`设备错误: ${event.deviceId}, ${event.error.message}`);
    });
    
    // 设备控制事件
    this.deviceController.on('command', (event) => {
      logger.info(`命令执行成功: 设备=${event.deviceId}, 标签=${event.tagName}, 值=${event.value}`);
    });
    
    this.deviceController.on('commandError', (event) => {
      logger.error(`命令执行失败: 设备=${event.deviceId}, 标签=${event.tagName}, 值=${event.value}, 错误=${event.error.message}`);
    });
  }

  /**
   * 初始化应用
   */
  async initialize() {
    try {
      logger.info('初始化PLC通信应用');
      
      // 初始化所有设备
      for (const device of config.devices) {
        try {
          let adapter;
          
          // 根据品牌创建适配器
          if (device.brand === 'Siemens') {
            adapter = new SiemensPLCAdapter(device);
          } else if (device.brand === 'Rockwell') {
            adapter = new RockwellPLCAdapter(device);
          } else {
            logger.error(`不支持的PLC品牌: ${device.brand}`);
            continue;
          }
          
          // 存储适配器
          this.adapters.set(device.id, adapter);
          
          // 添加到数据采集器和设备控制器
          this.dataCollector.addDevice(device.id, adapter);
          this.deviceController.addDevice(device.id, adapter);
          
          logger.info(`初始化设备: ${device.id}, ${device.name}`);
        } catch (error) {
          logger.error(`初始化设备失败: ${device.id}, ${error.message}`);
        }
      }
      
      return true;
    } catch (error) {
      logger.error(`初始化应用失败: ${error.message}`);
      return false;
    }
  }

  /**
   * 启动应用
   */
  async start() {
    try {
      logger.info('启动PLC通信应用');
      
      // 启动数据采集
      await this.dataCollector.start();
      
      logger.info('PLC通信应用已启动');
      return true;
    } catch (error) {
      logger.error(`启动应用失败: ${error.message}`);
      return false;
    }
  }

  /**
   * 停止应用
   */
  async stop() {
    try {
      logger.info('停止PLC通信应用');
      
      // 停止数据采集
      await this.dataCollector.stop();
      
      logger.info('PLC通信应用已停止');
      return true;
    } catch (error) {
      logger.error(`停止应用失败: ${error.message}`);
      return false;
    }
  }

  /**
   * 发送控制命令
   * @param {string} deviceId - 设备ID
   * @param {string} tagName - 标签名称
   * @param {any} value - 控制值
   */
  async sendCommand(deviceId, tagName, value) {
    return await this.deviceController.sendCommand(deviceId, tagName, value);
  }

  /**
   * 批量发送控制命令
   * @param {string} deviceId - 设备ID
   * @param {Array<{tagName: string, value: any}>} commands - 命令数组
   */
  async sendBatchCommands(deviceId, commands) {
    return await this.deviceController.sendBatchCommands(deviceId, commands);
  }

  /**
   * 读取设备数据
   * @param {string} deviceId - 设备ID
   * @param {string} tagName - 标签名称
   */
  async readTag(deviceId, tagName) {
    const adapter = this.adapters.get(deviceId);
    if (!adapter) {
      throw new Error(`设备不存在: ${deviceId}`);
    }
    
    return await adapter.readTag(tagName);
  }

  /**
   * 读取设备所有数据
   * @param {string} deviceId - 设备ID
   */
  async readAllTags(deviceId) {
    const adapter = this.adapters.get(deviceId);
    if (!adapter) {
      throw new Error(`设备不存在: ${deviceId}`);
    }
    
    return await adapter.readAllTags();
  }

  /**
   * 读取历史数据
   * @param {string} deviceId - 设备ID
   * @param {string} date - 日期 (YYYY-MM-DD)
   */
  readHistoricalData(deviceId, date) {
    return this.dataCollector.readHistoricalData(deviceId, date);
  }

  /**
   * 读取命令历史
   * @param {string} deviceId - 设备ID
   * @param {string} date - 日期 (YYYY-MM-DD)
   */
  readCommandHistory(deviceId, date) {
    return this.deviceController.readCommandHistory(deviceId, date);
  }
}

module.exports = PLCCommunicationApp;
